package jse.log;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import jse.Config;

public class JseLogAdapter implements LogAdapter {

    public Log getLogger(String className) {
        return JseLog.me();
    }

    public boolean canWork() {
        return true;
    }

    /**
     * 默认的Log,输出到System.out和System.err
     * 
     * @author Young(sunonfire@gmail.com)
     * @author Wendal(wendal1985@gmail.com)
     */
    public static class JseLog extends AbstractLog {

        private final static JseLog me = new JseLog();
        
        private static boolean warned;

        static JseLog me() {
            if (! warned) {
                me.info("Log init! impl JseLog. log Leve = %s",Config.getLogLevel());
                warned = true;
            }
            return me;
        }

        private JseLog() {
            setLevel(Config.getLogLevel());
        }

        public void debug(Object message, Throwable t) {
            if (isDebugEnabled())
                printOut("DEBUG",message, t);
        }

        public void error(Object message, Throwable t) {
            if (isErrorEnabled())
                errorOut("ERROR",message, t);
        }

        public void fatal(Object message, Throwable t) {
            if (isFatalEnabled())
                errorOut("FATAL",message, t);
        }

        public void info(Object message, Throwable t) {
            if (isInfoEnabled())
                printOut("INFO",message, t);
        }

        public void trace(Object message, Throwable t) {
            if (isTraceEnabled())
                printOut("TRACE",message, t);
        }

        public void warn(Object message, Throwable t) {
            if (isWarnEnabled())
                errorOut("WARN",message, t);
        }

        private void printOut(String level, Object message, Throwable t) {
            System.out.printf("%s %s [%s] %s\n", new Date(), level, Thread.currentThread().getName(),message);
            if (t != null)
                t.printStackTrace(System.out);
        }

        private void errorOut(String level, Object message, Throwable t) {
            System.err.printf("%s %s [%s] %s\n", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH).format(new Date()), level, Thread.currentThread().getName(),message);
            if (t != null)
                t.printStackTrace(System.err);
        }

        @Override
        protected void log(int level, Object message, Throwable tx) {
            switch (level) {
            case LEVEL_FATAL:
                fatal(message, tx);
                break;
            case LEVEL_ERROR:
                error(message, tx);
                break;
            case LEVEL_WARN:
                warn(message, tx);
                break;
            case LEVEL_INFO:
                info(message, tx);
                break;
            case LEVEL_DEBUG:
                debug(message, tx);
                break;
            case LEVEL_TRACE:
                trace(message, tx);
                break;
            }
        }

		@Override
		public void fatal(String fmt, Object... args) {
			fatalf(fmt, args);
		}

		@Override
		public void error(String fmt, Object... args) {
			errorf(fmt, args);
		}

		@Override
		public void warn(String fmt, Object... args) {
			warnf(fmt, args);
		}

		@Override
		public void info(String fmt, Object... args) {
			infof(fmt, args);
		}

		@Override
		public void debug(String fmt, Object... args) {
			debugf(fmt, args);
		}

		@Override
		public void trace(String fmt, Object... args) {
			tracef(fmt, args);
		}

    }
}
